/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.tchepannou.limbe.mail;

import com.tchepannou.limbe.Context;
import com.tchepannou.limbe.impl.AbstractController;
import com.tchepannou.util.MimeUtil;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  <code>MailControllers</code> are the core of email processing.
 *  They are made up of actions (public methods) that are executed for each mail to deliver.
 * </p>
 * <p>
 *  Each mail action render a view located in the <code>/mail/</code> directory,
 *  corresponding to the name of the controller and action after executing code in the action.
 *  For example, the action <code>PostMailController.send()</code> will render the view <code>/mail/post/send.vm</code>.
 *  The email view has the following structure:
 * </p>
 * <ul>
 *  <li>The 1st line is the subject of the email to deliver</li>
 *  <li>The following line is the body of the email to deliver</li>
 * <ul>
 * 
 * @author herve
 */
public class MailController
    extends AbstractController
{
    //-- Attributes
    private String _template;
    private String __name;
    private MailContext _context;
    private InternetAddress _from;
    private InternetAddress _replyTo;
    private List<InternetAddress> _to = new ArrayList<InternetAddress> ();
    private List<InternetAddress> _cc = new ArrayList<InternetAddress> ();
    private List<InternetAddress> _bcc = new ArrayList<InternetAddress> ();
    private List<Attachment> _attachments = new ArrayList<Attachment> ();
    private String _contentType = MimeUtil.TEXT;
    private String _subject;
    private String _body;
    private String _encoding = "utf-8";
    private Map<String, Object> _viewVariables = new HashMap<String, Object> ();

    //-- Controller override
    @Override
    public Context getContext ()
    {
        return getMailContext ();
    }


    //-- Public methods
    public void addTo (String address) throws MessagingException, IOException
    {
        add(_to, new InternetAddress(address));
    }
    public void addTo (String to, String displayName) throws MessagingException, IOException
    {
        add(_to, new InternetAddress(to, displayName));
    }


    public void addCc (String address) throws MessagingException, IOException
    {
        add(_cc, new InternetAddress(address));
    }
    public void addCc (String address, String displayName) throws MessagingException, IOException
    {
        add(_cc, new InternetAddress(address, displayName));
    }

    public void addBcc (String address) throws MessagingException, IOException
    {
        add(_bcc, new InternetAddress(address));
    }
    public void addBcc (String address, String displayName) throws MessagingException, IOException
    {
        add(_bcc, new InternetAddress(address, displayName));
    }

    private void add(List<InternetAddress> lst, InternetAddress address)
    {
        if (address != null)
        {
            lst.add(address);
        }
    }

    public void addAttachment (Attachment attachment)
    {
        _attachments.add (attachment);
    }

    public boolean hasAttachments ()
    {
        return !_attachments.isEmpty ();
    }

    public boolean hasRecipients ()
    {
        return !_to.isEmpty () || !_cc.isEmpty () || !_bcc.isEmpty ();
    }

    /**
     * Add a view variable
     *
     * @param name  Name of the variable
     * @param value Value of the variable
     */
    public void addViewVariable (String name, Object value)
    {
        _viewVariables.put (name, value);
    }

    /**
     * Add a set of view variables
     */
    public void addViewVariables (Map<String, Object> vars)
    {
        if (vars != null)
        {
            _viewVariables.putAll (vars);
        }
    }

    public InternetAddress getReplyTo ()
    {
        return _replyTo;
    }

    public void setReplyTo (String address)  throws MessagingException, IOException
    {
        this._replyTo = new InternetAddress(address);
    }
    public void setReplyTo (String address, String displayName)  throws MessagingException, IOException
    {
        this._replyTo = new InternetAddress(address, displayName);
    }


    
    public InternetAddress getFrom ()
    {
        return _from;
    }
    public void setFrom (String address)  throws MessagingException, IOException
    {
        this._from = new InternetAddress(address);
    }
    public void setFrom (String address, String displayName)  throws MessagingException, IOException
    {
        this._from = new InternetAddress(address, displayName);
    }

    public List<InternetAddress> getTo ()
    {
        return _to;
    }

    public List<InternetAddress> getBcc ()
    {
        return _bcc;
    }

    public List<InternetAddress> getCc ()
    {
        return _cc;
    }

    public String getSubject ()
    {
        return _subject;
    }

    public String getBody ()
    {
        return _body;
    }

    public void setBody (String body)
    {
        _body = body;
    }

    public String getContentType ()
    {
        return _contentType;
    }

    public String getEncoding ()
    {
        return _encoding;
    }

    public MailContext getMailContext ()
    {
        return _context;
    }

    public void setMailContext (MailContext context)
    {
        _context = context;
    }

    public void setSubject (String subject)
    {
        this._subject = subject;
    }

    public void setEncoding (String encoding)
    {
        _encoding = encoding;
    }

    public void setContentType (String contentType)
    {
        _contentType = contentType;
    }

    public Map<String, Object> getViewVariables ()
    {
        return _viewVariables;
    }

    public Object getViewVariable (String name) { return _viewVariables.get(name); }

    /**
     * Returns the name of the controller
     */
    public String getName ()
    {
        if (__name == null)
        {
            __name = getName (getClass ());
        }
        return __name;
    }

    public List<Attachment> getAttachments ()
    {
        return _attachments;
    }

    /**
     * Returns the computed name of a controller
     */
    public static String getName (Class<? extends MailController> clazz)
    {
        String fqcn = clazz.getName ();
        int i = fqcn.lastIndexOf ('.');
        String name = i>0 ? fqcn.substring (i+1) : fqcn;

        String xname = name.endsWith ("MailController")
            ? name.substring (0, name.length ()-14)
            : name;
        return xname.substring (0, 1).toLowerCase () + xname.substring (1);
    }

    /**
     * Template to apply to the email.
     * This property is set by the anotation {@link com.tchepannou.limbe.interceptor.TemplateInterceptor}
     */
    public String getTemplate ()
    {
        return _template;
    }

    public void setTemplate (String template)
    {
        this._template = template;
    }
}
